In [1]:
import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow import keras
from tensorflow.keras import optimizers
import keras_cv
import numpy as np
from keras_cv import bounding_box
import os
# import resource
from keras_cv import visualization
import tqdm
import json
Using TensorFlow backend
In [3]:
with open("C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\output.json") as jsonfile:
j = json.load(jsonfile)
In [5]:
class_mapping = {c["id"]: c["name"] for c in j["categories"]}
In [6]:
class_mapping
Out[6]:
{0: 'ParkingUnavailable', 1: 'ParkingAvailable'}
In [12]:
image_paths = [f"C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\{d['file_name']}" for d in j["images"]]
In [59]:
image_paths
Out[59]:
['C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\0.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\10.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\11.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\12.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\13.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\14.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\15.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\17.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\18.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\19.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\2.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\20.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\22.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\24.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\25.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\26.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\27.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\28.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\29.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\3.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\4.png', 'C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\images\\5.png']
In [69]:
filenameinseq = []
for filename in image_paths:
filenameinseq.append(filename.split("\\")[-1].split(".")[0])
In [71]:
# filenameinseq
In [51]:
# classes = [[] for _ in image_paths]
# bounding_boxes = [[] for _ in image_paths]
In [72]:
# for a in j["annotations"]:
# idx = a["image_id"]
# print("------------------")
# print(idx)
# print("------------------")
# print(classes)
# print("-----------------------")
# classes[idx].append(a["category_id"])
# bounding_boxes[idx].append(a["bbox"])
In [87]:
from itertools import groupby
In [94]:
annotations = []
for a in j["annotations"]:
annotations.append(a)
In [124]:
count = 0
for a in annotations:
if a["image_id"] == 22:
count = count + 1
In [125]:
count
Out[125]:
24
In [100]:
grouped_classes = {
image_id: [item['category_id'] for item in group]
for image_id, group in groupby(annotations, key=lambda x: x['image_id'])
}
classes = list(grouped_classes.values())
In [105]:
bounding_boxes_dict = {
image_id: [item['bbox'] for item in group]
for image_id, group in groupby(annotations, key=lambda x: x['image_id'])
}
bounding_boxes = list(bounding_boxes_dict.values())
In [127]:
# i = 1
# for cla in bounding_boxes:
# print(i)
# print(cla)
# print(len(cla))
# i = i + 1
# print("----------------------")
In [128]:
bbox = tf.ragged.constant(bounding_boxes)
classes = tf.ragged.constant(classes)
image_paths = tf.ragged.constant(image_paths)
In [129]:
data = tf.data.Dataset.from_tensor_slices((image_paths, classes, bbox))
In [130]:
len(data)
Out[130]:
22
In [131]:
val_data = data.take(4)
train_data = data.skip(4)
In [132]:
def load_image(image_path):
image = tf.io.read_file(image_path)
image = tf.image.decode_jpeg(image, channels = 3)
return image
def load_dataset(image_path, classes, bbox):
image = load_image(image_path)
bounding_boxes = {
"classes": tf.cast(classes, dtype = tf.float32),
"boxes": bbox,
}
return {"images":tf.cast(image, tf.float32),
"bounding_boxes": bounding_boxes}
In [133]:
## Hyper Parameters
BATCH_SIZE = 4
In [134]:
augmenter = keras.Sequential(
layers = [
keras_cv.layers.RandomFlip(mode = "horizontal", bounding_box_format = "xywh"),
keras_cv.layers.RandomShear(x_factor = 0.2,
y_factor = 0.2,
bounding_box_format = "xywh"),
keras_cv.layers.JitteredResize(
target_size = (640, 640),
scale_factor = (0.75, 1.3),
bounding_box_format = "xywh"),
]
)
In [135]:
## Create Train dataset
train_ds = train_data.map(load_dataset, num_parallel_calls = tf.data.AUTOTUNE)
train_ds = train_ds.shuffle(BATCH_SIZE * 4)
train_ds = train_ds.ragged_batch(BATCH_SIZE, drop_remainder = True)
train_ds = train_ds.map(augmenter, num_parallel_calls = tf.data.AUTOTUNE)
In [136]:
## Create Validation Dataset
resizing = keras_cv.layers.Resizing(
640, 640, bounding_box_format = "xywh", pad_to_aspect_ratio = True
)
val_ds = val_data.map(load_dataset, num_parallel_calls = tf.data.AUTOTUNE)
val_ds = val_ds.shuffle(BATCH_SIZE * 4)
val_ds = val_ds.ragged_batch(BATCH_SIZE, drop_remainder = True)
val_ds = val_ds.map(resizing, num_parallel_calls = tf.data.AUTOTUNE)
In [137]:
def visualize_dataset(inputs, value_range, rows, cols, bounding_box_format):
inputs = next(iter(inputs.take(1)))
images, bounding_boxes = inputs["images"], inputs["bounding_boxes"]
visualization.plot_bounding_box_gallery(
images,
value_range=value_range,
rows=rows,
cols=cols,
y_true=bounding_boxes,
scale=5,
font_scale=0.7,
bounding_box_format=bounding_box_format,
class_mapping=class_mapping,
)
In [138]:
visualize_dataset(
train_ds, bounding_box_format="xywh", value_range = (0, 255), rows = 2, cols = 2
)
In [139]:
visualize_dataset(
val_ds, bounding_box_format="xywh", value_range = (0, 255), rows = 2, cols = 2
)
In [140]:
def dict_to_tuple(inputs):
return inputs["images"], bounding_box.to_dense(
inputs["bounding_boxes"], max_boxes = 32
)
train_ds = train_ds.map(dict_to_tuple, num_parallel_calls = tf.data.AUTOTUNE)
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
val_ds = val_ds.map(dict_to_tuple, num_parallel_calls = tf.data.AUTOTUNE)
val_ds = val_ds.prefetch(tf.data.AUTOTUNE)
In [141]:
## Global clipnorm helps to reduce exploding gradient
base_lr = 0.005
## Including a global_clipnorm is extreamly important in object detection tasks
optimizer = tf.keras.optimizers.SGD(
learning_rate = base_lr, momentum = 0.9, global_clipnorm = 10.0
)
In [142]:
## Create a "RetinaNet" from ResNet50 backbone
model = keras_cv.models.RetinaNet.from_preset(
"resnet50_imagenet",
num_classes = len(class_mapping),
bounding_box_format = "xywh"
)
In [143]:
model.compile(
classification_loss = "focal",
box_loss = "smoothl1",
optimizer = optimizer,
)
In [146]:
model.fit(
train_ds,
validation_data = val_ds,
epochs = 10
)
Epoch 1/10 4/4 [==============================] - 153s 33s/step - loss: 1.8334 - box_loss: 0.7301 - classification_loss: 1.1033 - percent_boxes_matched_with_anchor: 0.4160 - val_loss: 1.7539 - val_box_loss: 0.7161 - val_classification_loss: 1.0378 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 2/10 4/4 [==============================] - 124s 31s/step - loss: 1.6902 - box_loss: 0.6990 - classification_loss: 0.9912 - percent_boxes_matched_with_anchor: 0.4395 - val_loss: 1.5999 - val_box_loss: 0.7233 - val_classification_loss: 0.8766 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 3/10 4/4 [==============================] - 122s 31s/step - loss: 1.5404 - box_loss: 0.6752 - classification_loss: 0.8652 - percent_boxes_matched_with_anchor: 0.3633 - val_loss: 1.5511 - val_box_loss: 0.7580 - val_classification_loss: 0.7931 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 4/10 4/4 [==============================] - 125s 31s/step - loss: 1.4819 - box_loss: 0.6729 - classification_loss: 0.8090 - percent_boxes_matched_with_anchor: 0.3730 - val_loss: 1.5481 - val_box_loss: 0.7603 - val_classification_loss: 0.7878 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 5/10 4/4 [==============================] - 123s 31s/step - loss: 1.3134 - box_loss: 0.6519 - classification_loss: 0.6615 - percent_boxes_matched_with_anchor: 0.3145 - val_loss: 1.3787 - val_box_loss: 0.7141 - val_classification_loss: 0.6645 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 6/10 4/4 [==============================] - 122s 31s/step - loss: 1.1990 - box_loss: 0.6198 - classification_loss: 0.5792 - percent_boxes_matched_with_anchor: 0.2969 - val_loss: 1.3703 - val_box_loss: 0.6934 - val_classification_loss: 0.6770 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 7/10 4/4 [==============================] - 123s 31s/step - loss: 1.3013 - box_loss: 0.6674 - classification_loss: 0.6339 - percent_boxes_matched_with_anchor: 0.3711 - val_loss: 1.3520 - val_box_loss: 0.6895 - val_classification_loss: 0.6625 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 8/10 4/4 [==============================] - 117s 29s/step - loss: 1.2316 - box_loss: 0.6602 - classification_loss: 0.5715 - percent_boxes_matched_with_anchor: 0.3984 - val_loss: 1.2859 - val_box_loss: 0.7061 - val_classification_loss: 0.5798 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 9/10 4/4 [==============================] - 115s 29s/step - loss: 1.2118 - box_loss: 0.6324 - classification_loss: 0.5794 - percent_boxes_matched_with_anchor: 0.3828 - val_loss: 1.3791 - val_box_loss: 0.7364 - val_classification_loss: 0.6427 - val_percent_boxes_matched_with_anchor: 0.1250 Epoch 10/10 4/4 [==============================] - 123s 31s/step - loss: 1.1913 - box_loss: 0.6300 - classification_loss: 0.5613 - percent_boxes_matched_with_anchor: 0.3457 - val_loss: 1.3211 - val_box_loss: 0.7567 - val_classification_loss: 0.5644 - val_percent_boxes_matched_with_anchor: 0.1250
Out[146]:
<keras.src.callbacks.History at 0x1afaa690760>
In [148]:
model.save("C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\carParkingModel.keras")
In [149]:
import tensorflow as tf
# Load the model
loaded_model = tf.keras.models.load_model("C:\\Users\\write\\Desktop\\Computer_Vision_CNN_Projects\\Car_Parking\\CarParkingKaggle\\CarParking\\carParkingModel.keras")
WARNING:tensorflow:`compile()` was not called as part of model loading because the model's `compile()` method is custom. All subclassed Models that have `compile()` overridden should also override `get_compile_config()` and `compile_from_config(config)`. Alternatively, you can call `compile()` manually after loading.
In [155]:
# def visualize_detections(model, dataset, bounding_box_format):
# images, y_true = next(iter(dataset.take(1)))
# y_pred = model.predict(images)
# y_pred = bounding_box.to_ragged(y_pred)
# visualization.plot_bounding_box_gallery(
# images,
# value_range = (0, 255),
# bounding_box_format = bounding_box_format,
# y_true = y_true,
# y_pred = y_pred,
# scale = 4,
# rows = 2,
# cols = 2,
# show = True,
# font_scale = 0.7,
# class_mapping = class_mapping,
# )
In [160]:
# def visualize_detections(model, dataset, bounding_box_format):
# images, y_true = next(iter(dataset.take(1)))
# images = tf.expand_dims(images, axis=0) # Add batch dimension
# y_pred = model.predict(images)
# y_pred = bounding_box.to_ragged(y_pred)
# visualization.plot_bounding_box_gallery(
# images,
# value_range=(0, 255),
# bounding_box_format=bounding_box_format,
# y_true=y_true,
# y_pred=y_pred,
# scale=4,
# rows=2,
# cols=2,
# show=True,
# font_scale=0.7,
# class_mapping=class_mapping,
# )
In [161]:
## Set IOU and confidence Thresholds
model.prediction_decoder = keras_cv.layers.MultiClassNonMaxSuppression(
bounding_box_format = "xywh",
from_logits = True,
iou_threshold = 0.5,
confidence_threshold = 0.75
)
In [187]:
import tensorflow as tf
import matplotlib.pyplot as plt
from keras_cv import visualization
# Function to load and preprocess a single image
def load_and_preprocess_image(image_path):
image = tf.io.read_file(image_path)
image = tf.image.decode_jpeg(image, channels=3)
image = tf.image.resize(image, (640, 640)) # Resize to model input size
image = tf.cast(image, tf.float32) / 255.0 # Normalize to [0, 1]
return image
# Load the image
image_path = r"C:\Users\write\Desktop\Computer_Vision_CNN_Projects\Car_Parking\CarParkingKaggle\CarParking\OutOfSample\31.png"
image = load_and_preprocess_image(image_path)
# Add a batch dimension to the image
image = tf.expand_dims(image, axis=0)
# Make predictions
predictions = model.predict(image)
# Extract predictions
boxes = predictions['boxes'] # Bounding boxes
scores = predictions['confidence'] # Confidence scores
classes = predictions['classes'] # Class predictions
num_detections = predictions['num_detections'] # Number of detections
# Visualize results
def visualize_predictions(image, boxes, classes, scores, class_mapping, num_detections, threshold=0.1):
# Convert the image to numpy for visualization
image_np = image.numpy()[0] # Remove batch dimension
plt.figure(figsize=(10, 10))
plt.imshow(image_np)
for i in range(num_detections[0]):
if scores[0][i] >= threshold: # Check if score is above threshold
box = boxes[0][i].numpy() # Get the bounding box
class_id = int(classes[0][i].numpy()) # Get the class id
class_name = class_mapping[class_id] # Map to class name
# Draw the bounding box and label on the image
visualization.draw_bounding_box_on_image(
image_np,
box,
class_name=class_name,
score=scores[0][i].numpy(),
color='red',
thickness=2
)
plt.axis('off')
plt.show()
# Call the visualize function
visualize_predictions(image, boxes, classes, scores, class_mapping, num_detections)
1/1 [==============================] - 2s 2s/step
In [188]:
predictions = model.predict(image)
1/1 [==============================] - 2s 2s/step
In [189]:
predictions
Out[189]:
{'boxes': array([[[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.],
[-1., -1., -1., -1.]]], dtype=float32),
'confidence': array([[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1.]], dtype=float32),
'classes': array([[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1.,
-1., -1., -1., -1., -1., -1., -1., -1., -1.]], dtype=float32),
'num_detections': array([0])}
In [ ]:
In [ ]: